package com.bianguo.android.iocdemo.view.widget;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;

import com.bianguo.android.eventbuslibrary.utils.MLog;
import com.bianguo.android.iocdemo.R;
import com.bianguo.android.iocdemo.view.widget.listener.SplashStateListener;
import com.bianguo.android.iocdemo.view.widget.state.ExpandState;
import com.bianguo.android.iocdemo.view.widget.state.MerginState;
import com.bianguo.android.iocdemo.view.widget.state.RotateState;
import com.bianguo.android.iocdemo.view.widget.state.SplashState;

public class SplashView extends View implements SplashStateListener {

    //动画时间
    private int animTime = 1000;
    //6个小圆的画笔
    private Paint mPaint;
    //扩散圆的画笔
    private Paint mHolePaint;
    //画布的中心坐标
    private float mCenterX, mCenterY;
    //小圆的半径
    private float mCircleR = 18;
    //旋转圆的半径
    private float mRotateRadius = 90;
    //当前旋转圆的半径
    private float mCurrentRotateRadius = mRotateRadius;
    //当前小圆的旋转角度
    private float mCurrentAngle;
    //当前扩散圆的半径
    private float mCurrentHoleRadius;
    //6个小圆的颜色
    private int[] mCircleColors;
    //
    private SplashState mState;
    //画布对角线
    private float mDistance;

    public SplashView(Context context) {
        this(context, null);
    }

    public SplashView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SplashView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs) {
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

        mHolePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mHolePaint.setStyle(Paint.Style.STROKE);
        mHolePaint.setColor(Color.WHITE);

        mCircleColors = context.getResources().getIntArray(R.array.splash_circle_colors);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (mState == null) {
            mState = new RotateState(animTime);
            mState.setStateListener(this);
        }
        mState.drawState(canvas);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mCenterX = w * 1f / 2;
        mCenterY = h * 1f / 2;
        MLog.i("w = " + w + ", mCenterX = " + mCenterX + ", h = " + h + ", mCenterY = " + mCenterY);
        mDistance = (float) (Math.hypot(w, h) / 2);
    }

    private void drawCircles(Canvas canvas) {
        //计算每两个小球之间的角度（弧度制）
        //2π / 小球的个数
        float rotateAngle = (float) (2 * Math.PI / mCircleColors.length);
        for (int i = 0; i < mCircleColors.length; i++) {
            float angle = i * rotateAngle + mCurrentAngle;
            // x / r = cosA
            // y / r = sinA
            float x = (float) (mCurrentRotateRadius * Math.cos(angle) + mCenterX);
            float y = (float) (mCurrentRotateRadius * Math.sin(angle) + mCenterY);
            mPaint.setColor(mCircleColors[i]);
            canvas.drawCircle(x, y, mCircleR, mPaint);
        }
    }

    private void drawBackground(Canvas canvas) {
        if (mCurrentHoleRadius > 0) {
            float strokeWidth = mDistance - mCurrentHoleRadius;
            float radius = strokeWidth / 2 + mCurrentHoleRadius;
            MLog.i("strokeWidth = " + strokeWidth + ", radius = " + radius);
            mHolePaint.setStrokeWidth(strokeWidth);
            canvas.drawCircle(mCenterX, mCenterY, radius, mHolePaint);
        } else {
            canvas.drawColor(Color.WHITE);
        }
    }

    @Override
    public void onDrawState(SplashState state, Canvas canvas) {
        drawBackground(canvas);
        if (state instanceof RotateState || state instanceof MerginState) {
            drawCircles(canvas);
        }
    }

    @Override
    public void onAnimEnd(SplashState state) {
        if (state instanceof RotateState) {
            mState = new MerginState(mCircleR, mRotateRadius, animTime);
            mState.setStateListener(this);
        } else if (state instanceof MerginState) {
            mState = new ExpandState(mCircleR, mDistance);
            mState.setStateListener(this);
        }
    }

    @Override
    public void updateCurrentAngle(float angle) {
        mCurrentAngle = angle;
        invalidate();
    }

    @Override
    public void updateCurrentRotateRadius(float radius) {
        mCurrentRotateRadius = radius;
        invalidate();
    }

    @Override
    public void updateCurrentHoleRadius(float radius) {
        mCurrentHoleRadius = radius;
        invalidate();
    }

//    private class RotateState extends SplashState {
//
//        public RotateState() {
//            animator = ValueAnimator.ofFloat(0, (float) (2 * Math.PI));
//            animator.setDuration(animTime);
//            animator.setRepeatCount(2);
//            animator.setInterpolator(new LinearInterpolator());
//            animator.addUpdateListener(valueAnimator -> {
//                mCurrentAngle = (float) valueAnimator.getAnimatedValue();
//                invalidate();
//            });
//            animator.addListener(new AnimatorListenerAdapter() {
//                @Override
//                public void onAnimationEnd(Animator animation) {
//                    super.onAnimationEnd(animation);
//                    mState = new MerginState();
//                }
//            });
//            animator.start();
//        }
//
//        @Override
//        public void drawState(Canvas canvas) {
//            drawBackground(canvas);
//            drawCircles(canvas);
//        }
//    }
//
//    private class MerginState extends SplashState {
//
//        public MerginState() {
//            animator = ValueAnimator.ofFloat(mCircleR, mRotateRadius);
//            animator.setDuration(animTime);
//            animator.setInterpolator(new OvershootInterpolator());
//            animator.addUpdateListener(valueAnimator -> {
//                mCurrentRotateRadius = (float) valueAnimator.getAnimatedValue();
//                invalidate();
//            });
//            animator.addListener(new AnimatorListenerAdapter() {
//                @Override
//                public void onAnimationEnd(Animator animation) {
//                    super.onAnimationEnd(animation);
//                    mState = new ExpandState();
//                }
//            });
//            animator.reverse();
//        }
//
//        @Override
//        public void drawState(Canvas canvas) {
//            drawBackground(canvas);
//            drawCircles(canvas);
//        }
//    }
//
//    private class ExpandState extends SplashState {
//
//        public ExpandState() {
//            animator = ValueAnimator.ofFloat(mCircleR, mDistance);
//            animator.setDuration(600);
//            animator.setInterpolator(new LinearInterpolator());
//            animator.addUpdateListener(valueAnimator -> {
//                mCurrentHoleRadius = (float) valueAnimator.getAnimatedValue();
//                invalidate();
//            });
//            animator.start();
//        }
//
//        @Override
//        public void drawState(Canvas canvas) {
//            drawBackground(canvas);
//        }
//    }
}
